﻿<!doctype html>
<meta charset=utf-8>
<html>
<head>
    <title>Test Actions</title>
    <style>
      div { padding:0px; margin: 0px; }
      #trackPointer { position: fixed; }
      #resultContainer { width: 600px; height: 60px; }
      .area { width: 100px; height: 50px; background-color: #ccc; }
      .block { width: 5px; height: 5px; border: solid 1px red; }
      #dragArea { position: relative; }
      #dragTarget { position: absolute; top:22px; left:47px;}
    </style>
    <script>
        "use strict";
        var els = {};
        var allEvents = { events: [] };
        function displayMessage(message) {
            document.getElementById("events").innerHTML = "<p>" + message + "</p>";
        }

        function appendMessage(message) {
            document.getElementById("events").innerHTML += "<p>" + message + "</p>";
        }

        /**
         * Escape |key| if it's in a surrogate-half character range.
         *
         * Example: given "\ud83d" return "U+d83d".
         *
         * Otherwise JSON.stringify will convert it to U+FFFD (REPLACEMENT CHARACTER)
         * when returning a value from executeScript, for example.
         */
        function escapeSurrogateHalf(key) {
          if (typeof key !== "undefined" && key.length === 1) {
            var charCode = key.charCodeAt(0);
            var highSurrogate = charCode >= 0xD800 && charCode <= 0xDBFF;
            var surrogate = highSurrogate || (charCode >= 0xDC00 && charCode <= 0xDFFF);
            if (surrogate) {
              key = "U+" + charCode.toString(16);
            }
          }
          return key;
        }

        function recordKeyboardEvent(event) {
          var key = escapeSurrogateHalf(event.key);
          allEvents.events.push({
            "code": event.code,
            "key": key,
            "which": event.which,
            "location": event.location,
            "ctrl": event.ctrlKey,
            "meta": event.metaKey,
            "shift": event.shiftKey,
            "repeat": event.repeat,
            "type": event.type
          });
          appendMessage(event.type + " " +
              "code: " + event.code + ", " +
              "key: " + key + ", " +
              "which: " + event.which + ", " +
              "keyCode: " + event.keyCode);
        }

        function recordPointerEvent(event) {
          if (event.type === "contextmenu") {
            event.preventDefault();
          }
          allEvents.events.push({
            "type": event.type,
            "button": event.button,
            "buttons": event.buttons,
            "pageX": event.pageX,
            "pageY": event.pageY,
            "ctrlKey": event.ctrlKey,
            "metaKey": event.metaKey,
            "altKey": event.altKey,
            "shiftKey": event.shiftKey,
            "target": event.target.id
          });
          appendMessage(event.type + " " +
              "button: " + event.button + ", " +
              "pageX: " + event.pageX + ", " +
              "pageY: " + event.pageY + ", " +
              "button: " + event.button + ", " +
              "buttons: " + event.buttons + ", " +
              "ctrlKey: " + event.ctrlKey + ", " +
              "altKey: " + event.altKey + ", " +
              "metaKey: " + event.metaKey + ", " +
              "shiftKey: " + event.shiftKey + ", " +
              "target id: " + event.target.id);
        }

        function recordFirstPointerMove(event) {
          recordPointerEvent(event);
          window.removeEventListener("mousemove", recordFirstPointerMove);
        }

        function grabOnce(event) {
          grab(event);
          els.dragTarget.removeEventListener("mousedown", grabOnce);
        }

        function dropOnce(moveHandler) {
          return function (event) {
            moveHandler(event);
            els.dragArea.removeEventListener("mouseup", dropOnce);
          }
        }

        function resetEvents() {
          allEvents.events.length = 0;
          displayMessage("");
        }

        function drop(moveHandler) {
          return function (event) {
            els.dragArea.removeEventListener("mousemove", moveHandler);
            els.dragTarget.style.backgroundColor = "yellow";
            els.dragTarget.addEventListener("mousedown", grab);
            recordPointerEvent(event);
          };
        }

        function move(el, offsetX, offsetY, timeout) {
          return function(event) {
            setTimeout(function() {
              el.style.top = event.clientY + offsetY + "px";
              el.style.left = event.clientX + offsetX + "px";
            }, timeout);
          };
        }

        function grab(event) {
          event.target.style.backgroundColor = "red";
          let boxRect = event.target.getBoundingClientRect();
          let areaRect = event.target.parentElement.getBoundingClientRect();
          let moveHandler = move(
              event.target,
              // coordinates of dragTarget must be relative to dragArea such that
              // dragTarget remains under the pointer
              -(areaRect.left + (event.clientX - boxRect.left)),
              -(areaRect.top + (event.clientY - boxRect.top)),
              20);
          els.dragArea.addEventListener("mousemove", moveHandler);
          els.dragArea.addEventListener("mouseup", dropOnce(drop(moveHandler)));
        }

        document.addEventListener("DOMContentLoaded", function() {
          var keyReporter = document.getElementById("keys");
          keyReporter.addEventListener("keyup", recordKeyboardEvent);
          keyReporter.addEventListener("keypress", recordKeyboardEvent);
          keyReporter.addEventListener("keydown", recordKeyboardEvent);

          var outer = document.getElementById("outer");
          outer.addEventListener("click", recordPointerEvent);
          outer.addEventListener("dblclick", recordPointerEvent);
          outer.addEventListener("mousedown", recordPointerEvent);
          outer.addEventListener("mouseup", recordPointerEvent);
          outer.addEventListener("contextmenu", recordPointerEvent);

          window.addEventListener("mousemove", recordFirstPointerMove);
          //visual cue for mousemove
          var pointer = document.getElementById("trackPointer");
          window.addEventListener("mousemove", move(pointer, 15, 15, 30));
          // drag and drop
          els.dragArea = document.getElementById("dragArea");
          els.dragTarget = document.getElementById("dragTarget");
          els.dragTarget.addEventListener("mousedown", grabOnce);
        });
    </script>
</head>
<body>
  <div id="trackPointer" class="block"></div>
  <div>
    <h2>KeyReporter</h2>
    <input type="text" id="keys" size="80">
  </div>
  <div>
    <h2>ClickReporter</h2>
    <div id="outer" class="area">
    </div>
  </div>
  <div>
    <h2>DragReporter</h2>
    <div id="dragArea" class="area">
      <div id="dragTarget" class="block"></div>
    </div>
  </div>
  <div id="resultContainer">
    <h2>Events</h2>
    <div id="events"></div>
  </div>
</body>
</html>
